home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1998…tember: Reference Library / Dev.CD Sep 98 RL1.toast / Technical Documentation / develop / develop Issue 23 / develop Issue 23 code / QuickTime Music / BigEasy2.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-12-02  |  46.3 KB  |  2,358 lines  |  [TEXT/CWIE]

  1. /*
  2.     File:        BigEasy2.c
  3.  
  4.     Copyright:    © 1990-1992, 1994 by Apple Computer, Inc., all rights reserved.
  5.  
  6.     This file is used in these builds: Warhol
  7.  
  8.     Change History (most recent first):
  9.  
  10.         <41+>     22-9-94    dvb    universal headers    
  11.         <41>     22-9-94    dvb        
  12.         <40+>     17-8-94    dvb        allocate gx job when pagesetup, no sooner, coz its slow.
  13.         <40>     17-8-94    dvb        GX Printing
  14.         <39>      9-8-94    dvb        
  15.         <38>     27-7-94    dvb        installquititem
  16.         <37+>     5/27/94    dvb        InstallQuitItem
  17.         <37>     5/27/94    dvb        .
  18.         <35>      1/7/93    dvb        Compile under mpw.
  19.         <34>      1/6/93    dvb        Built in window-copy command.
  20.         <33>     4/23/92    dvb        Test checkout from new project
  21.         <32>     4/13/92    dvb        Pass activate/deactivates to back windows.
  22.         <31>     3/22/92    dvb        QuitApp message.
  23.         <30>     1/20/92    dvb        Cool new features. Much easier appleevents.
  24.         <29>    12/19/91    JB        removing think 4.0 code
  25.         <28>    10/14/91    JB        added #ifdef to create old window ports for debugging
  26.         <27>     9/18/91    PH        support silly disk inserted events
  27.         <26>     8/12/91    MD        support for timing profiler nastiness
  28.         <25>      7/3/91    PH        qd. is bad under old think
  29.         <24>     6/28/91    dvb        Make it work with/without MacHeaders in LSC5.
  30.         <23>      6/4/91    PH        compilin'
  31.         <22>      6/3/91    dvb        Just hackin.
  32.         <21>     5/28/91    JB        Added prototypes for BigEasy Proc Ptrs
  33.         <20>     5/27/91    PH        to compile again...
  34.         <19>     5/25/91    JB        OLD_THINK_C && TOOLBOX_LINKED
  35.         <18>     5/23/91    PH        changes for THINK 5
  36.         <17>     5/22/91    PH        new style prototypes
  37.         <16>      5/6/91    PH        nifty line after about...
  38.         <15>      5/5/91    dvb        Latest features, and App-Events for document open.
  39.        
  40.         <14>     4/25/91    JB        Changing to new THINK C interface files
  41.         <13>     4/19/91    PH        i like content clicks
  42.         <12>     4/19/91    dvb        Add WindowEventProc
  43.         <11>     3/29/91    PH        minor activate fix
  44.         <10>     3/29/91    dvb        Repair deactivate vs closewindow conflict, roll in latest cool
  45.                                     features.
  46.          <9>      3/9/91    dvb        Adjust to work with or without (LSC) mac headers
  47.          <8>      3/7/91    JB        Adjusting for using MacHeaders
  48.          <7>      3/1/91    dvb        Trivial new functions
  49.          <6>     2/24/91    dvb        Various cool new calls
  50.          <5>     2/18/91    dvb        Miscellaneous Updates
  51.          <4>      1/9/91    JB        Increasing ItemsPerMenu & #Menus
  52.          <3>    11/21/90    JB        Changes for INIT & mpw compatability
  53.          <2>    11/17/90    dvb        Pass on unused command-keys to document windows
  54.         <1>    11/17/90    dvb        New again after 1st CD pressing! Yay!
  55.  
  56.     To Do:
  57. */
  58.  
  59. /* file: BigEasy2.c
  60.   *
  61.   * Started 30 June 1988, more or less.
  62.   *
  63.   * A set of routines to allow the quick development
  64.   * of simple Macintosh applications.
  65.   * :)
  66.   */
  67.  
  68.  
  69. #define BigEasy2
  70.  
  71. #include <QuickDraw.h>
  72. #include <Gestalt.h>
  73. #include <Events.h>
  74. #include <AppleEvents.h>
  75. #include <Resources.h>
  76. #include <Menus.h>
  77. #include <ToolUtils.h>
  78. #include <Menus.h>
  79. #include <Windows.h>
  80. #include <Dialogs.h>
  81. #include <Memory.h>
  82. #include <devices.h>
  83. #include <Fonts.h>
  84. #include <Scrap.h>
  85. #include <SegLoad.h>
  86.  
  87. //#undef BigEasyGXPrinting
  88.  
  89. #ifdef BigEasyGXPrinting
  90.     #include <PrintingManager.h>
  91.     #include <Graphics Toolbox.h>
  92.     #include <Graphics Routines.h>
  93. #endif
  94.  
  95.  
  96.  
  97. /* #define THINK_C_PROFILE /* */
  98. #if defined(TIMING_PROFILE) || defined(STACK_KILLER)
  99.     #include "stack killer.h"
  100. #endif
  101.  
  102. #include "BigEasy2.h"
  103.  
  104.  
  105.  
  106. #ifdef BigEasyGXPrinting
  107.     #define WantsGX 1
  108. #else
  109.     #define WantsGX 0
  110. #endif
  111.  
  112. /*----------------
  113.     Limits
  114. ----------------*/
  115. #define kMMax 10            /* Number of menus in menubar */
  116. #define kMIMax 50            /* Number of items per menu */
  117. #define kMenuNameMax 32        /* Length of a menu title */
  118.  
  119. #define kStagLimX 97
  120. #define kStagLimY 37
  121.  
  122. /*----------------
  123.     Constants
  124. ----------------*/
  125. #define    kOSEvent                        app4Evt    /* event used by MultiFinder */
  126. #define    kSuspendResumeMessage            1        /* high byte of suspend/resume event message */
  127. #define    kResumeMask                    1        /* bit of message field for resume vs. suspend */
  128.  
  129. #define kWinPosType 'bewP'
  130. #define trapExitToShell 0xA9F4
  131.  
  132.  
  133.  
  134. /*----------------
  135.     Major BigEasy2 Structures
  136. ----------------*/
  137.  
  138. typedef struct TEasyWindow
  139.     {
  140.     Boolean wUsed;
  141.     long iNum;
  142.     long flags;
  143.     Boolean wGrowable;
  144.     beUpdateProcPtr wUpdateProc;
  145.     beClickProcPtr wClickProc;
  146.     beKeyProcPtr wKeyProc;
  147.     beGoAwayProcPtr wGoAwayProc;
  148.     beWNumCallProcPtr wZoomProc;
  149.     beActivateProcPtr wActivateProc;
  150.     beDeactivateProcPtr wDeactivateProc;
  151.     beIdleProcPtr wIdleProc;
  152.     beResizeProcPtr wResizeProc;
  153.     beGrowWindowProcPtr wGrowWindowProc;
  154.     beMoveWindowProcPtr wMoveWindowProc;
  155.     beEventProcPtr wEventProc;
  156.     WindowPtr wWindow;
  157. #ifdef BigEasyGXPrinting
  158.     gxJob job;
  159. #endif
  160.     } TEasyWindow;
  161.  
  162. typedef struct
  163.     {
  164.     short ref;
  165.     char mark;
  166.     char enable;
  167.     char cmdEquiv;
  168.     beMenuProcPtr proc;
  169.     } TEasyMenuItem;
  170.  
  171. /*----------------
  172.     Globals
  173. ----------------*/
  174. static short gIdleSeed;
  175. static Rect gResizeLim = {50,50,1000,1000};
  176. static TEasyWindow **gEasyWindowListH;            /* Handle to array of window objects    */
  177. static TEasyWindow *gEasyWindowList;            /* Pointer to array of window objects    */
  178. static short gEasyWindowListSize;                /* Number of window objects allocated    */
  179.  
  180. /*** Menus ***/
  181. static MenuHandle gMenuHandleList[kMMax];        /* MenuHandles indexed by MenuID's         */
  182. static short gMenuLength[kMMax];
  183. static char gMenuName[kMMax][kMenuNameMax];
  184. static TEasyMenuItem gMenu[kMMax][kMIMax];
  185. static short gMenuCount;                        /* How many menus defined */
  186. static short gCurrentMenu;                        /* the one to add to */
  187. static MenuHandle gMenuEdit;                    /* Which one is the edit menu? */
  188.  
  189. /*** Phantom Menu ***/
  190. static MenuHandle phantomMenuH = 0;
  191.  
  192. /*** About ***/
  193. static beAboutProcPtr gAboutProc;
  194. static char gAboutS0[256];
  195.  
  196. /*** Application Edit Commands ***/
  197. static beWNumCallProcPtr gAppUndoProc,gAppCutProc,gAppCopyProc,gAppPasteProc,gAppClearProc;
  198.  
  199. static beMenuProcPtr gAppPageSetupProc=0,gAppPrintProc=0;
  200.  
  201. /*** Global Status ***/
  202. static beOpenAppProcPtr gMasterOpenAppProc;
  203. static beOpenDocProcPtr gMasterOpenDocProc;
  204. static beQuitAppProcPtr gMasterQuitAppProc;
  205.  
  206. static beAboutProcPtr gMasterIdleProc;
  207. static short gStagX,gStagY;
  208. static WindowPtr gLastFrontIdle;
  209. static short gLastFrontWindowNumber;
  210. static short gSleep;
  211. static short gCoolDragState;
  212. static Point gCoolDragPoint;
  213. static short gCoolDragWindowNumber;
  214. static TEasyWindow *gCoolDragEW;
  215. static Boolean gInvalidMenuBar;
  216.  
  217. static void *gOldExitToShell;
  218.  
  219. PicHandle GetWindowPICT(TEasyWindow *thisEasyWindow);
  220.  
  221. /*----------------
  222.     Prototypes
  223. ----------------*/
  224. static void InitToolbox(void);
  225. static void CheckMenubar(void);
  226. static void EventLoop(void);
  227. static void InitBigEasy(void);
  228. static void ExitBigEasy(void);
  229. static void InstallMyExitToShell(void);
  230. static pascal void MyExitToShell(void);
  231. static void GetGrowRect(WindowPtr,Rect*);
  232. static void EnoughEasyWindows(short);
  233. static void FrontDAEdits(void);
  234. static TEasyWindow *GoodWNum(short);
  235. static Boolean CoolBigEasyCmdKeys(short key);
  236.  
  237. static void DoMyAbout(void);
  238. static void BEUndo(short);
  239. static void BECopy(short);
  240. static void BECut(short);
  241. static void BEPaste(short);
  242. static void BEClear(short);
  243. static void BENull(void);
  244. void BEPageSetup(short n, short menuItem, short menuRef);
  245. void BEPrint(short n, short menuItem, short menuRef);
  246.  
  247. static void MenuClick(Point p);
  248. static void DeleteIndexedMenuItem(short menu,short item);
  249. static Boolean DoKeyPress(long k);
  250. static void MenuPoint(long theclick);
  251. static void StartMenus(void);
  252. static short ScanWindowList(WindowPtr w);
  253. static void DoMouseClick(EventRecord *event);
  254. static void MyDrawGrowIcon(WindowPtr w);
  255.  
  256. static pascal OSErr BigEasyOpenAppThang(AppleEvent *theEvent, AppleEvent *reply,long refCon);
  257. static pascal OSErr BigEasyOpenDocThang(AppleEvent *theEvent, AppleEvent *reply,long refCon);
  258. static pascal OSErr BigEasyQuitAppThang(AppleEvent *theEvent, AppleEvent *reply,long refCon);
  259. static OSErr MissedAEParameters (AppleEvent *message);
  260.  
  261. Boolean ActivateWindow(WindowPtr w, Boolean activate);
  262.  
  263. #ifdef BigEasyGXPrinting
  264. void MakeSureWeHaveJob(TEasyWindow *thisWindow);
  265. #endif
  266.  
  267. void main(void);
  268.  
  269. /*----------------
  270.     Some useful routines
  271. ----------------*/
  272.  
  273. void InitToolbox(void)
  274.     {
  275.     InitGraf(&qd.thePort);
  276.     InitFonts();
  277.     FlushEvents(0xffff,0);
  278.     InitWindows();
  279.     InitMenus();
  280.     InitDialogs(0);
  281.     TEInit();
  282.     InitCursor();
  283.     }
  284.  
  285.  
  286. void GetGrowRect(WindowPtr w,Rect *r)
  287.     {
  288.     register Rect *gr;
  289.  
  290.     gr = r;
  291.     *gr = w->portRect;
  292.     gr->left = gr->right - 15;
  293.     gr->top = gr->bottom - 15;
  294.     }
  295.  
  296. void GoWatch(void)
  297.     {
  298.     SetCursor(*(Cursor**)GetCursor(4));
  299.     }
  300.  
  301. void GoArrow(void)
  302.     {
  303.     SetCursor(&qd.arrow);
  304.     }
  305.  
  306. void GoCursor(short c)
  307. /*
  308.   * Attempt to set to cursor ID c,
  309.   * but skip it if not there.
  310.   */
  311.     {
  312.     register Cursor **cur;
  313.  
  314.     cur = (Cursor **)GetCursor(c);
  315.     if(cur)
  316.         SetCursor(*cur);
  317.     }
  318.  
  319. static void EnoughEasyWindows(short n)
  320. /*
  321.   * If there are less than n window objects in the list,
  322.   * grow the handle appropriately.
  323.   */
  324.     {
  325.     short i;
  326.  
  327.     n++;
  328.     if(gEasyWindowListSize < n)
  329.         {
  330.         HUnlock((Handle)gEasyWindowListH);
  331.         SetHandleSize((Handle)gEasyWindowListH,sizeof(TEasyWindow) * (long)n);
  332.         HLock((Handle)gEasyWindowListH);
  333.         gEasyWindowList = *gEasyWindowListH;
  334.  
  335.         for(i = gEasyWindowListSize; i < n; i++)
  336.             gEasyWindowList[i].wUsed = 0;
  337.  
  338.         gEasyWindowListSize = n;
  339.         }
  340.     }
  341.  
  342. static TEasyWindow *GoodWNum(short n)
  343. /*
  344.   * return true if n is the number of an
  345.   * existing, used window.
  346.   */
  347.     {
  348.     register TEasyWindow *thisWindow;
  349.     if(n<0 || n>=gEasyWindowListSize)
  350.         return 0;
  351.     thisWindow = &gEasyWindowList[n];
  352.     if(thisWindow->wUsed)
  353.         return thisWindow;
  354.     else
  355.         return 0;
  356.     }
  357.  
  358.  
  359. static void FrontDAEdits(void)
  360. /*
  361.  * Check the front window. If it's a DA,
  362.  * enable all edit menu options.
  363.  */
  364.     {
  365.     WindowRecord *w;
  366.  
  367.     w = (WindowRecord*)FrontWindow();
  368.     if(w->windowKind < 0)                                    /* Any click in a DA window: */
  369.         EnDisEdits(1,1,1,1,1);                                /* enable edit menu. */
  370.     }
  371.  
  372.  
  373. void DoMyAbout(void)
  374.     {
  375.     DialogPtr d;
  376.     Handle h;
  377.     short hit;
  378.  
  379.     if(gAboutProc)
  380.         (*gAboutProc)();
  381.     else
  382.         {
  383.         h = GetResource('DLOG',1962);                            /* does it exist? */
  384.         if( (ResError()==0) && (h!=nil) )
  385.             {
  386.             ParamText((StringPtr)gAboutS0,0,0,0);
  387.             d = GetNewDialog(1962,0,(WindowPtr)-1);
  388.             ModalDialog(nil,&hit);
  389.             DisposDialog(d);
  390.             }
  391.         }
  392.     }
  393.  
  394. void SetMasterIdle(r)
  395.     beAboutProcPtr r;
  396.     {
  397.     gMasterIdleProc = r;
  398.     }
  399.  
  400. void SetWindowResizeProc(short n,beResizeProcPtr resizeProc)
  401. /*
  402.   * Sets the procedure which gets called when the window is resized
  403.   */
  404.     {
  405.     TEasyWindow *thisWindow;
  406.  
  407.     thisWindow = GoodWNum(n);
  408.     if(thisWindow)
  409.         thisWindow->wResizeProc = resizeProc;
  410.     }
  411.  
  412. void SetWindowGrowWindowProc(short n,beGrowWindowProcPtr growWindowProc)
  413. /*
  414.   * Sets the procedure which gets called when the window grows.
  415.   *   Allows alternate to GrowWindow.
  416.   */
  417.     {
  418.     TEasyWindow *thisWindow;
  419.  
  420.     thisWindow = GoodWNum(n);
  421.     if(thisWindow)
  422.         thisWindow->wGrowWindowProc = growWindowProc;
  423.     }
  424.  
  425. void SetWindowMoveProc(short n,beMoveWindowProcPtr moveWindowProc)
  426.     {
  427.     TEasyWindow *thisWindow;
  428.  
  429.     thisWindow = GoodWNum(n);
  430.     if(thisWindow)
  431.         thisWindow->wMoveWindowProc = moveWindowProc;
  432.     }
  433.  
  434.  
  435. void SetWindowZoomProc(short n,beWNumCallProcPtr zoomProc)
  436.     {
  437.     register TEasyWindow *thisWindow;
  438.  
  439.     thisWindow = GoodWNum(n);
  440.     if(thisWindow)
  441.         thisWindow->wZoomProc = zoomProc;
  442.     }
  443.  
  444. void SetWindowEventProc(short n,beEventProcPtr eventProc)
  445.     {
  446.     register TEasyWindow *thisWindow;
  447.  
  448.     thisWindow = GoodWNum(n);
  449.     if(thisWindow)
  450.         thisWindow->wEventProc = eventProc;
  451.     }
  452.  
  453. long GetWindowFlags(short n)
  454.     {
  455.     TEasyWindow *thisWindow;
  456.  
  457.     if(!(thisWindow = GoodWNum(n)))
  458.         return 0;
  459.  
  460.     return thisWindow->flags;
  461.     }
  462.  
  463. void SetWindowFlags(short n,long flags)
  464.     {
  465.     TEasyWindow *thisWindow;
  466.  
  467.     if(!(thisWindow = GoodWNum(n)))
  468.         return;
  469.  
  470.     thisWindow->flags = flags;
  471.     }
  472.  
  473. void SetAbout(StringPtr progName,StringPtr s0,beAboutProcPtr aboutProc)
  474. /*
  475.  * Sets the program's name in the about box, and
  476.  * sets the second string as ParamText 0 (^0)
  477.  * for the about dialog, 1962.
  478.  */
  479.     {
  480.     short i;
  481.     
  482.     SetItem(gMenuHandleList[1],1,(StringPtr)progName);
  483.  
  484.     for(i=0; i<256; i++)
  485.         gAboutS0[i] = *s0++;
  486.  
  487.     gAboutProc = aboutProc;
  488.     } 
  489.  
  490. /*----------------
  491.     Error Handling
  492. ----------------*/
  493.  
  494. void FailNil(long x)
  495. /*
  496.   * If x is zero, post an error
  497.   * alert and quit the program.
  498.   */
  499.     {
  500.     if(!x)
  501.         {
  502.         Alert(200,nil);
  503.         Debugger();
  504.         ExitToShell();
  505.         }
  506.     }
  507.  
  508. void FailOSErr(long x)
  509. /*
  510.   * If x isn't zero, post an error
  511.   * alert and quit the program.
  512.   */
  513.     {
  514.     if(x)
  515.         {
  516.         Debugger();
  517.         Alert(200,nil);
  518.         ExitToShell();
  519.         }
  520.     }
  521.  
  522. /*----------------
  523.     Some inherent methods
  524. ----------------*/
  525.  
  526. void BEUndo(short n)
  527.     {
  528.     if(!SystemEdit(0) && gAppUndoProc)
  529.         (*gAppUndoProc)(n);
  530.     }
  531.  
  532. void BECut(short n)
  533.     {
  534.     if(!SystemEdit(2) && gAppCutProc)
  535.         (*gAppCutProc)(n);
  536.     }
  537.  
  538. PicHandle GetWindowPICT(TEasyWindow *tew)
  539.     {
  540.     Rect visBounds;
  541.     beUpdateProcPtr fp;
  542.     PicHandle picH;
  543.  
  544.     SetPort(tew->wWindow);    /* Set port to window    */
  545.  
  546.     visBounds = qd.thePort->portRect;
  547.     InsetRect(&visBounds,-1,-1);
  548.     ForeColor(blackColor);
  549.     BackColor(whiteColor);
  550.     PenSize(1,1);
  551.  
  552.     picH = OpenPicture(&visBounds);
  553.     ClipRect(&visBounds);
  554.     FrameRect(&visBounds);
  555.  
  556.     fp = tew->wUpdateProc;
  557.     if(fp)
  558.         (*fp)(tew->iNum);                            /* Call drawing proc    */
  559.  
  560.     SetOrigin(0,0);
  561.  
  562.     ClosePicture();
  563.     ClipRect(&gBigRect);
  564.  
  565.     return picH;
  566.     }
  567.  
  568.  
  569. void BECopy(short n)
  570.     {
  571.     TEasyWindow *thisEasyWindow;
  572.  
  573.     if(!SystemEdit(3))
  574.         {
  575.         thisEasyWindow = GoodWNum(n);
  576.         if(thisEasyWindow->flags & wCopyDraw)
  577.             /*
  578.              * 
  579.              */
  580.             {
  581.             PicHandle picH;
  582.  
  583.             picH = GetWindowPICT(thisEasyWindow);
  584.  
  585.             HLock((Handle)picH);
  586.             ZeroScrap();
  587.             PutScrap(GetHandleSize((Handle)picH),'PICT',(Ptr)*picH);
  588.  
  589.             KillPicture(picH);
  590.             }
  591.         else if(gAppCopyProc)
  592.             (*gAppCopyProc)(n);
  593.         }
  594.     }
  595.  
  596. void BEPaste(short n)
  597.     {
  598.     if(!SystemEdit(4) && gAppPasteProc)
  599.         (*gAppPasteProc)(n);
  600.     }
  601.  
  602. void BEClear(short n)
  603.     {
  604.     if(!SystemEdit(5) && gAppClearProc)
  605.         (*gAppClearProc)(n);
  606.     }
  607.  
  608. void BENull(void){}
  609.  
  610.  
  611. void BEPageSetup(short n, short menuItem, short menuRef)
  612.     {
  613.     OSErr err;
  614.     long oldMenus;
  615.  
  616. #ifdef BigEasyGXPrinting
  617.     TEasyWindow *tew;
  618.     gxDialogResult result;
  619.     gxEditMenuRecord editMenuRec;
  620.  
  621.     tew = GoodWNum(n);
  622.     if(tew->flags & wPrintDraw)
  623.         {
  624.         oldMenus = DisableAllMenus();
  625.     
  626.         editMenuRec.editMenuID = 0;
  627.         editMenuRec.cutItem = 0; 
  628.         editMenuRec.copyItem = 0;
  629.         editMenuRec.pasteItem = 0;
  630.         editMenuRec.clearItem = 0;
  631.         editMenuRec.undoItem = 0;
  632.         
  633.         MakeSureWeHaveJob(tew);
  634.         result = GXJobDefaultFormatDialog(tew->job,&editMenuRec);
  635.         err = GXGetJobError(tew->job);
  636.     
  637.         EnableAllMenus(oldMenus);
  638.         }
  639.     else
  640. #endif
  641.         {
  642.         if(gAppPageSetupProc)
  643.             (*gAppPageSetupProc)(n,menuItem,menuRef);
  644.         }
  645.     }
  646.  
  647. void BEPrint(short n, short menuItem, short menuRef)
  648.     {
  649.     OSErr err;
  650.     PicHandle picH;
  651.     Rect pictR,centeredR,pageR;
  652.     Point p;
  653.     Str255 s;
  654.     long oldMenus;
  655.  
  656. #ifdef BigEasyGXPrinting
  657.     TEasyWindow *tew;
  658.     gxFormat format;
  659.     gxTranslationStatistic stats;
  660.     gxRectangle pageSize,paperSize;
  661.     gxDialogResult result;
  662.     gxEditMenuRecord editMenuRec;
  663.     gxShape sh;
  664.  
  665.     tew = GoodWNum(n);
  666.     if(tew->flags & wPrintDraw)
  667.         {
  668.         oldMenus = DisableAllMenus();
  669.     
  670.         editMenuRec.editMenuID = 0;
  671.         editMenuRec.cutItem = 0; 
  672.         editMenuRec.copyItem = 0;
  673.         editMenuRec.pasteItem = 0;
  674.         editMenuRec.clearItem = 0;
  675.         editMenuRec.undoItem = 0;
  676.         
  677.         MakeSureWeHaveJob(tew);
  678.         result = GXJobPrintDialog(tew->job,&editMenuRec);
  679.         err = GXGetJobError(tew->job);
  680.     
  681.         picH = GetWindowPICT(tew);
  682.     
  683.         pictR = (**picH).picFrame;
  684.         p.h = p.v = 0;
  685.  
  686.         /*
  687.           * Center the image in the page rectangle
  688.           */
  689.         format = GXGetJobFormat(tew->job,1);
  690.         GXGetFormatDimensions(format,&pageSize,&paperSize);
  691.         pageR.top = pageSize.top >> 16;
  692.         pageR.bottom = pageSize.bottom >> 16;
  693.         pageR.left = pageSize.left >> 16;
  694.         pageR.right = pageSize.right >> 16;
  695.         centeredR = pictR;
  696.         OffsetRect(¢eredR,
  697.                 (pageR.left + pageR.right - pictR.left - pictR.right + 1) >> 1,
  698.                 (pageR.top + pageR.bottom - pictR.top - pictR.bottom + 1) >> 1);
  699.     
  700.         sh = GXConvertPICTToShape(picH, gxDefaultOptionsTranslation, &pictR, ¢eredR, p, nil, &stats);
  701.     
  702.         GetWTitle(tew->wWindow,s);
  703.     
  704.         GXStartJob(tew->job,s,0);
  705.         err = GXGetJobError(tew->job);
  706.         GXPrintPage(tew->job,1,nil,sh);
  707.         err = GXGetJobError(tew->job);
  708.         GXFinishJob(tew->job);
  709.         err = GXGetJobError(tew->job);
  710.         GXDisposeShape(sh);
  711.     
  712.         EnableAllMenus(oldMenus);
  713.         }
  714. #endif
  715.         {
  716.         if(gAppPageSetupProc)
  717.             (*gAppPageSetupProc)(n,menuItem,menuRef);
  718.         }
  719.     }
  720.  
  721.  
  722. /*----------------
  723.     Menu Action Routines
  724. ----------------*/
  725.  
  726. Boolean DoKeyPress(long k)
  727.     {
  728.     register long thePoint;
  729.     register Boolean didIt;
  730.  
  731.     thePoint = MenuKey((char)k);
  732.     didIt = (thePoint>>16) != 0;
  733.     if(didIt)
  734.         MenuPoint(thePoint);
  735.  
  736.     return didIt;
  737.     }
  738.     
  739. void MenuClick(Point p)
  740.     {
  741.     KeyMap     theKeys;
  742.     Boolean    putBack = false;
  743.     short    oldID;
  744.     
  745.     if (phantomMenuH) {
  746.     GetKeys(theKeys);
  747.         
  748.         if ((theKeys[1]&4) == 0) {
  749.             putBack = true;
  750.             oldID = (**phantomMenuH).menuID;
  751.             DeleteMenu( oldID );
  752.             }
  753.         }
  754.     MenuPoint(MenuSelect(p));
  755.     if (putBack)
  756.         {
  757.         InsertMenu(phantomMenuH,oldID);
  758.         }
  759.     }
  760.  
  761. void MenuPoint(long theclick)
  762.     {
  763.     register short mID,mItem;
  764.     char DAname[30];
  765.     short wNum;
  766.     TEasyWindow *thisWindow;
  767.     register beMenuProcPtr aProc;
  768.     register TEasyMenuItem *emi;
  769.  
  770.     mID = theclick>>16;
  771.     mItem = theclick & 0xffff;
  772.  
  773.     if(mID == 0) return;
  774.  
  775.     if(mID == 1)                            /* Apple menu */
  776.         {
  777.         if(mItem == 1)                        /* Its either the about box */
  778.             DoMyAbout();
  779.         else    
  780.             {                                    /* Or a DA */
  781.             GetItem(gMenuHandleList[1],mItem,(StringPtr)DAname);
  782.             OpenDeskAcc((StringPtr)DAname);
  783.             }
  784.         }
  785.     else
  786.         {
  787.         wNum = gLastFrontWindowNumber;
  788.         thisWindow = GoodWNum(wNum);
  789.         if(thisWindow)                                    /* if one of our window in front, setport    */
  790.             SetPort(thisWindow->wWindow);
  791.  
  792.         emi = &gMenu[mID][0];
  793.         aProc = emi->proc;
  794.         if(aProc)                                        /* call the menu's routine, if any        */
  795.             (*aProc)(wNum,mItem,gMenu[mID][mItem].ref);
  796.  
  797.         emi = &gMenu[mID][mItem];
  798.         aProc = emi->proc;
  799.         if(aProc)                                        /* call the item's routine, if any        */
  800.             (*aProc)(wNum,mItem,emi->ref);
  801.         }
  802.  
  803.     HiliteMenu(0);
  804.     }
  805.  
  806. char dAbout[] = "\pAbout ";
  807.  
  808. void StartMenus(void)
  809. /*
  810.  * Start with just an About box, and some DA's.
  811.  */
  812.     {
  813.     char aboutS[255];
  814.     MenuHandle applemenu;
  815.  
  816.     BlockMove(&dAbout[0],aboutS,dAbout[0]+1);            /* "About" */
  817.     BlockMove((StringPtr )0x910 + 1,aboutS + aboutS[0] + 1, *(StringPtr )0x910); /* ProgName */
  818.     aboutS[0] += *((StringPtr )0x910);
  819.     aboutS[aboutS[0] + 1] = '…';
  820.     aboutS[0]++;
  821.  
  822.     applemenu = NewMenu(1,(StringPtr)"\p");                /* Apple menu: ID 1                    */
  823.     AppendMenu(applemenu,(StringPtr)aboutS);
  824.     AppendMenu(applemenu,(StringPtr)"\p(-");
  825.     AddResMenu(applemenu,'DRVR');
  826.     InsertMenu(applemenu,0);
  827.     DrawMenuBar();
  828.     gMenuHandleList[1] = applemenu;
  829.     gMenu[1][0].enable = true;
  830.  
  831.     gMenuCount = 1;                        /* Next menu added will be ID 2        */
  832.     gCurrentMenu = 1;
  833.     gMenuLength[1] = 0;                    /* No items, really, in Apple menu        */
  834.     }
  835.  
  836. MenuHandle InstallMenu(StringPtr s,beMenuProcPtr action,short ref)
  837. /*
  838.  * Start a new menu with name s
  839.  */
  840.     {
  841.     register TEasyMenuItem *emi;
  842.     register MenuHandle mh;
  843.  
  844.     gMenuCount++;                                /* new menu                        */
  845.     gCurrentMenu = gMenuCount;
  846.  
  847.     if(*s > kMenuNameMax-1)
  848.         *s = kMenuNameMax-1;
  849.  
  850.     gMenuLength[gCurrentMenu] = 0;
  851.     mh = NewMenu(gCurrentMenu,(StringPtr)s);
  852.     gMenuHandleList[gCurrentMenu] = mh;
  853.     InsertMenu(mh,0);
  854.  
  855.     emi = &gMenu[gCurrentMenu][0];
  856.     emi->enable = ref >= 0;
  857.     if(!emi->enable)
  858.         {
  859.         DisableItem(mh,0);
  860.         ref =- ref;
  861.         }
  862.     emi->proc = action;
  863.     emi->ref = ref;
  864.  
  865.     gInvalidMenuBar = true;                    /* redraw soon */
  866.     BlockMove(s,gMenuName[gCurrentMenu],*s+1);
  867.     return mh;
  868.     }
  869.  
  870. static Str255 dQuitString = "\pQuit ";
  871. #define kQuitLength 5
  872. static Str15 dQuitCmdKey = "\p/Q";
  873.  
  874. void InstallQuitItem(beMenuProcPtr action,short ref)
  875.     {
  876.     short i,j;
  877.     StringPtr w;
  878.  
  879.     i = kQuitLength;
  880.  
  881.     w = (StringPtr)0x910;
  882.     j = *w++;
  883.     while(j--)
  884.         dQuitString[++i] = *w++;
  885.  
  886.     w = dQuitCmdKey;
  887.     j = *w++;
  888.     while(j--)
  889.         dQuitString[++i] = *w++;
  890.  
  891.     dQuitString[0] = i;
  892.  
  893.     InstallMenuItem(dQuitString,action,ref);
  894.     }
  895.  
  896.  
  897.  
  898. void InstallMenuItem(StringPtr s,beMenuProcPtr action,short ref)
  899. /*
  900.  * Add an item to the last menu, and associate a routine with it.
  901.  */
  902.     {
  903.     register MenuHandle mh;
  904.     register TEasyMenuItem *emi;
  905.     register short item;
  906.  
  907.  
  908.     mh = gMenuHandleList[gCurrentMenu];
  909.     gMenuLength[gCurrentMenu]++;
  910.     item = gMenuLength[gCurrentMenu];
  911.     emi = &gMenu[gCurrentMenu][item];
  912.  
  913.     if (ref < 0)
  914.         {
  915.         DisableItem(mh,item);
  916.         ref =- ref;
  917.         emi->enable = 0;
  918.         }
  919.     else
  920.         emi->enable = 1;
  921.  
  922.     AppendMenu(mh,(StringPtr)s);
  923.     emi->proc = action;
  924.     emi->ref = ref;
  925.     emi->mark = 0;
  926.     if(*(s+*s-1) == '/')
  927.         emi->cmdEquiv = *(s+*s);
  928.     else
  929.         emi->cmdEquiv = 0;
  930.     }
  931.  
  932. void RemoveMenuItem(short ref)
  933. /*
  934.  * Remove all menu items with
  935.  * refcon ref.
  936.  */
  937.     {
  938.     short menu;
  939.     short item;
  940.  
  941.     for(menu = 1; menu <= gMenuCount; menu++)
  942.         for(item = gMenuLength[menu]; item > 0; item--)
  943.             {
  944.             if(gMenu[menu][item].ref == ref)
  945.                 DeleteIndexedMenuItem(menu,item);
  946.             }
  947.     }
  948.  
  949. void DeleteIndexedMenuItem(short menu,short item)
  950.     {
  951.     StringPtr oldStrings;
  952.     MenuHandle mh;
  953.     short i;
  954.     short itemCount;
  955.     register TEasyMenuItem *emi;
  956.     register StringPtr w;
  957.  
  958.     itemCount = gMenuLength[menu];
  959.     mh = gMenuHandleList[menu];
  960.     oldStrings = (StringPtr)NewPtrClear(256 * (itemCount));
  961.     FailNil((long)oldStrings);
  962.  
  963.     for(i = 1; i<=itemCount; i++)
  964.         GetItem(mh,i,(StringPtr)&oldStrings[(i-1)*256]);
  965.  
  966.     DeleteMenu(menu);
  967.     DisposeMenu(mh);
  968.  
  969.     mh = NewMenu(menu,(StringPtr)gMenuName[menu]);
  970.     emi = &gMenu[menu][1];
  971.     w = oldStrings;
  972.     for(i = 1; i<=itemCount; i++)
  973.         {
  974.         if(i != item)
  975.             {
  976.             if(emi->cmdEquiv)
  977.                 {
  978.                 *(w+*w+1) = '/';
  979.                 *(w+*w+2) = emi->cmdEquiv;
  980.                 *w = *w + 2;
  981.                 }
  982.             AppendMenu(mh,(StringPtr)w);
  983.             }
  984.         emi++;
  985.         w += 256;
  986.         }
  987.  
  988.     emi = &gMenu[menu][item];
  989.     for(i = item; i<itemCount; i++)
  990.         {
  991.         *emi = *(emi+1);
  992.         emi++;
  993.         }
  994.  
  995.     gMenuLength[menu]--;
  996.     itemCount--;
  997.  
  998.     emi = &gMenu[menu][1];
  999.     for(i = 1; i<=itemCount; i++)
  1000.         {
  1001.         if(!emi->enable)
  1002.             DisableItem(mh,i);
  1003.         if(emi->mark)
  1004.             SetItemMark(mh,i,emi->mark);
  1005.         emi++;
  1006.         }
  1007.  
  1008.     InsertMenu(mh,menu+1);
  1009.     DisposPtr((Ptr)oldStrings);
  1010.     }
  1011.  
  1012. void InstallEditMenu(beWNumCallProcPtr Xundo,
  1013.         beWNumCallProcPtr Xcut,
  1014.         beWNumCallProcPtr Xcopy,
  1015.         beWNumCallProcPtr Xpaste,
  1016.         beWNumCallProcPtr Xclear)
  1017.     /*
  1018.      * Start an edit menu, and put the first six things in.
  1019.      */
  1020.     {
  1021.     gAppUndoProc = Xundo;
  1022.     gAppCutProc = Xcut;
  1023.     gAppCopyProc = Xcopy;
  1024.     gAppPasteProc = Xpaste;
  1025.     gAppClearProc = Xclear;
  1026.  
  1027.     InstallMenu("\pEdit",nil,0);
  1028.     InstallMenuItem("\px/Z",(beMenuProcPtr)BEUndo,-mUndo);            /* barfs because it is static */
  1029.     InstallMenuItem("\p(-",(beMenuProcPtr)BENull,0);
  1030.     InstallMenuItem("\px/X",(beMenuProcPtr)BECut,-mCut);
  1031.     InstallMenuItem("\px/C",(beMenuProcPtr)BECopy,-mCopy);
  1032.     InstallMenuItem("\px/V",(beMenuProcPtr)BEPaste,-mPaste);
  1033.     InstallMenuItem("\px/B",(beMenuProcPtr)BEClear,-mClear);
  1034.  
  1035.     gMenuEdit = gMenuHandleList[gCurrentMenu];
  1036.  
  1037.     EnDisEdits(-1,-1,-1,-1,-1);
  1038.     }
  1039.  
  1040. void InstallPrintItems(beMenuProcPtr pageSetup,beMenuProcPtr print)
  1041.     {
  1042.     gAppPageSetupProc = pageSetup;
  1043.     gAppPrintProc = print;
  1044.  
  1045.     InstallMenuItem("\pPage Setup…/π",(beMenuProcPtr)BEPageSetup,-mPageSetup);
  1046.     InstallMenuItem("\pPrint…/P",(beMenuProcPtr)BEPrint,-mPrint);
  1047.     }
  1048.  
  1049. void SetMenuItem(short ref,char enable,char isMarked,char mark,StringPtr s)
  1050. /*
  1051.   * Set all items with the reference number to the
  1052.   * enable/disable state, with mark, and name s.
  1053.   * pass enable + to enable, - to disable, and
  1054.   * zero to leave alone.
  1055.   */
  1056.     {
  1057.     short m,i;
  1058.     MenuHandle mh;
  1059.     register TEasyMenuItem *emi;
  1060.  
  1061.     for(m=1; m<=gMenuCount; m++)
  1062.         {
  1063.         mh = gMenuHandleList[m];
  1064.         for(i=gMenuLength[m]; i>=0; i--)
  1065.             {
  1066.             emi = &gMenu[m][i];
  1067.             if(emi->ref == ref)
  1068.                 {
  1069.                 if(enable)
  1070.                     {
  1071.                     if(!i)
  1072.                         gInvalidMenuBar = true;
  1073.                     if(enable > 0)
  1074.                         {
  1075.                         emi->enable = 1;
  1076.                         EnableItem(mh,i);
  1077.                         }
  1078.                     else
  1079.                         {
  1080.                         emi->enable = 0;
  1081.                         DisableItem(mh,i);
  1082.                         }
  1083.                     }
  1084.                 if(i > 0)                    /* these only apply to items */
  1085.                     {
  1086.                     if(isMarked)
  1087.                         if(isMarked > 0)
  1088.                             {
  1089.                             emi->mark = mark;
  1090.                             SetItemMark(mh,i,mark);
  1091.                             //CheckItem(mh,i,true);
  1092.                             }
  1093.                         else
  1094.                             {
  1095.                             emi->mark = 0;
  1096.                             SetItemMark(mh,i,0);
  1097.                             }
  1098.                     if(s)
  1099.                         SetItem(mh,i,(StringPtr)s);
  1100.                     }
  1101.                 }
  1102.             }
  1103.         }
  1104.     }
  1105.  
  1106.  
  1107.  
  1108. void EnDisEdits(short Eundo,short Ecut,short Ecopy,short Epaste,short Eclear)
  1109. /*
  1110.  * For each edit menu entry,
  1111.  * -1=disable, 1=enable, 0=leave alone.
  1112.  */
  1113.     {
  1114.     SetMenuItem(mUndo,Eundo,false,0,"\pUndo");
  1115.     SetMenuItem(mCut,Ecut,false,0,"\pCut");
  1116.     SetMenuItem(mCopy,Ecopy,false,0,"\pCopy");
  1117.     SetMenuItem(mPaste,Epaste,false,0,"\pPaste");
  1118.     SetMenuItem(mClear,Eclear,false,0,"\pClear");
  1119.     }
  1120.  
  1121. MenuHandle SetCurrentMenu(short ref)
  1122. /*
  1123.  * Set which menu will take
  1124.  * future "InstallMenuItem"s.
  1125.  */
  1126.     {
  1127.     register short i;
  1128.  
  1129.     for(i = 0; i<gMenuCount; i++)
  1130.         {
  1131.         if(gMenu[i][0].ref == ref)
  1132.             {
  1133.             gCurrentMenu = i;
  1134.             return gMenuHandleList[i];
  1135.             }
  1136.         }
  1137.     return 0;
  1138.     }
  1139.  
  1140. long DisableAllMenus(void)
  1141. /*
  1142.  * Disable all menus, as for a modal dialog,
  1143.  * and return a long with the masks of which should get reenabled.
  1144.  */
  1145.     {
  1146.     long result;
  1147.     long mask;
  1148.     TEasyMenuItem *emi;
  1149.     short i;
  1150.  
  1151.     result = 0;
  1152.     mask = 1;
  1153.     for(i = 0; i<kMMax; i++)
  1154.         {
  1155.         emi = &gMenu[i][0];
  1156.         if(emi->enable)
  1157.             {
  1158.             DisableItem(gMenuHandleList[i],0);
  1159.             result |= mask;
  1160.             }
  1161.         mask <<= 1;
  1162.         }
  1163.     DrawMenuBar();
  1164.     return result;
  1165.     }
  1166.  
  1167. void EnableAllMenus(long saveMenus)
  1168. /*
  1169.  * Enable menus according to the mask returned by DisableAllMenus().
  1170.  */
  1171.     {
  1172.     long mask;
  1173.     short i;
  1174.  
  1175.     mask = 1;
  1176.     for(i = 0; i<kMMax; i++)
  1177.         {
  1178.         if(saveMenus & mask)
  1179.             EnableItem(gMenuHandleList[i],0);
  1180.         mask <<= 1;
  1181.         }
  1182.     DrawMenuBar();
  1183.     }
  1184.  
  1185.  
  1186. short ScanWindowList(WindowPtr w)
  1187. /*
  1188.   * return a window number from a WindowPeek,
  1189.   * or -1 if no known window.
  1190.   */
  1191.     {
  1192.     short i;
  1193.     TEasyWindow *wo;
  1194.  
  1195.     wo= &gEasyWindowList[0];
  1196.  
  1197.     for(i=0; i<gEasyWindowListSize; i++)
  1198.         {
  1199.         if (wo->wUsed && (wo->wWindow==w))
  1200.             return i;
  1201.         wo++;
  1202.         }
  1203.     return -1;
  1204.     }
  1205.  
  1206.  
  1207. /*----------------
  1208.     Mouse Action Routines
  1209. ----------------*/
  1210. void DoMouseClick(EventRecord *event)
  1211.     {
  1212.     WindowPtr w;
  1213.     short part;
  1214.     register short wNum;
  1215.     register TEasyWindow *thisEasyWindow;
  1216.     Point p;
  1217.     Rect r;
  1218.     Boolean tookEvent;
  1219.  
  1220.     p = event->where;
  1221.     part = FindWindow (p, &w);
  1222.     wNum = ScanWindowList(w);
  1223.     thisEasyWindow = GoodWNum(wNum);
  1224.  
  1225.     switch (part)
  1226.         {
  1227.         case inDesk:
  1228.             break;
  1229.  
  1230.         case inMenuBar:
  1231.             MenuClick(p);
  1232.             break;
  1233.         
  1234.         case inSysWindow:
  1235.             SystemClick(event,w);
  1236.             break;
  1237.         
  1238.         case inContent:
  1239.         contentClick:
  1240.             if (w != FrontWindow())                /* If clicked on a non-front window, */
  1241.                 SelectWindow(w);                            /* bring it to the front. */
  1242.             else if(thisEasyWindow)                            /* Click on front window: give click */
  1243.                 {                                        /* to window's click routine. */
  1244.                 SetPort(w);
  1245.                 GlobalToLocal(&p);
  1246.  
  1247.                 ClipRect(&gBigRect);
  1248.                 SetOrigin(0,0);
  1249.  
  1250.                 if(thisEasyWindow && thisEasyWindow->wEventProc)
  1251.                     (*thisEasyWindow->wEventProc)(wNum,event,&tookEvent);
  1252.                 else
  1253.                     tookEvent = false;
  1254.  
  1255.                 if(!tookEvent)
  1256.                     {
  1257.                     register beClickProcPtr fp;
  1258.  
  1259.                     fp = thisEasyWindow->wClickProc;
  1260.                     if(fp)
  1261.                         (*fp)(wNum,p,
  1262.                                 event->modifiers);
  1263.                     }
  1264.                 }
  1265.             break;
  1266.  
  1267.         case inDrag:
  1268.             if(((thisEasyWindow->flags & wCoolDrag)!=0)
  1269.                     ^ ((event->modifiers & optionKey)!=0))
  1270.                 {
  1271.                 gCoolDragPoint = event->where;
  1272.                 gCoolDragState = 1;
  1273.                 gCoolDragEW = thisEasyWindow;
  1274.                 gCoolDragWindowNumber = wNum;
  1275.                 if(!(event->modifiers & 256))
  1276.                     SelectWindow(w);
  1277.                 }
  1278.             else
  1279.                 if(Button())                                /* for quick title-bar clicks */
  1280.                     {
  1281.                     beMoveWindowProcPtr fp;
  1282.  
  1283.                     DragWindow(w,event->where,&gBigRect);
  1284.                     fp = thisEasyWindow->wMoveWindowProc;
  1285.                     if(fp)
  1286.                         (fp)(wNum);                    
  1287.                     }
  1288.                 else
  1289.                     SelectWindow(w);
  1290.             break;
  1291.  
  1292.         case inGrow:
  1293.             if(thisEasyWindow && (thisEasyWindow->flags & wGrowable))
  1294.                 {
  1295.                 long oldSize,newSize;
  1296.                 beGrowWindowProcPtr fp;
  1297.                 beResizeProcPtr rsfp;
  1298.                 
  1299.                 SetPort(w);
  1300.                 GetGrowRect(w,&r);
  1301.                 InvalRect(&r);
  1302.  
  1303.                 fp = thisEasyWindow->wGrowWindowProc;
  1304.                 if(fp)
  1305.                     (*fp)(&newSize,wNum,w,event->where,&gResizeLim);
  1306.                 else
  1307.                     newSize = GrowWindow(w,event->where,&gResizeLim);
  1308.  
  1309.                 if(newSize)
  1310.                     {
  1311.                     rsfp = thisEasyWindow->wResizeProc;
  1312.                     if(rsfp)
  1313.                         {
  1314.                         oldSize = ((long)(w->portRect.bottom-w->portRect.top)<<16) |
  1315.                                 (w->portRect.right-w->portRect.left);
  1316.                         (*rsfp)(wNum,(Point *)&oldSize,(Point *)&newSize,event->modifiers);
  1317.                         }
  1318.                     else
  1319.                         SizeWindow(w,newSize&0xffff,newSize>>16,1);
  1320.                     GetGrowRect(w,&r);
  1321.                     InvalRect(&r);
  1322.                     }
  1323.                 }
  1324.             else
  1325.                 goto contentClick;
  1326.             break;
  1327.  
  1328.         case inGoAway:
  1329.             if(thisEasyWindow)
  1330.                 if (TrackGoAway(w,event->where))
  1331.                     {
  1332.                     beGoAwayProcPtr fp;
  1333.                     
  1334.                     fp = thisEasyWindow->wGoAwayProc;
  1335.                     if(fp)
  1336.                         (*fp)(wNum);
  1337.                     }
  1338.             break;
  1339.  
  1340.         /*
  1341.          * The following way to handle zoom only
  1342.          * applies to zooming to 1 state.  This does
  1343.          * not handle zooming in and out between 2
  1344.          * states.  Check IM IV.
  1345.          */
  1346.  
  1347.         case inZoomIn:    /* zoomBox */
  1348.         case inZoomOut:
  1349.             if(thisEasyWindow)
  1350.                 {
  1351.                 if (TrackBox(w,event->where,part))
  1352.                     {
  1353.                     beWNumCallProcPtr fp;
  1354.                     
  1355.                     fp = thisEasyWindow->wZoomProc;
  1356.                     if(fp)
  1357.                         (*fp)(wNum);
  1358.                     }
  1359.                 }
  1360.             break;
  1361.         }
  1362.     }
  1363.  
  1364. /*----------------
  1365.     Window Action Routines
  1366. ----------------*/
  1367.  
  1368. WindowPtr InstallWindow(short iNum,StringPtr iTitle,Rect *iRect,short iType,short iFlags,
  1369.         beUpdateProcPtr iUpdate,beClickProcPtr iClick,beKeyProcPtr iKey,beGoAwayProcPtr iGoAway,
  1370.         beActivateProcPtr iActivate,beDeactivateProcPtr iDeactivate,beIdleProcPtr iIdle)
  1371. /*
  1372.  * Add a window to BigEasy's list. If the window is
  1373.  * already up somewhere, bring it to the front and
  1374.  * visualize it.
  1375.  */
  1376.     {
  1377.     TEasyWindow *thisWindow;
  1378.     Rect stagRect,**oldPos;
  1379.     Boolean isVisible;
  1380.     RgnHandle rh;
  1381.     KeyMap km;
  1382.     Boolean opt;
  1383.  
  1384.     GetKeys(km);
  1385.  
  1386.     opt =km[58/8] &  (1<< (58%8) );
  1387.  
  1388.     isVisible = iNum>0;
  1389.     if(!isVisible)
  1390.         iNum = -iNum;
  1391.  
  1392.     EnoughEasyWindows(iNum);            /* Make sure there's space for new one        */
  1393.     thisWindow = &gEasyWindowList[iNum];
  1394.  
  1395.     if (thisWindow->wUsed)                /* something already assigned to this window? */
  1396.         {
  1397.         Show(iNum);
  1398.         goto goHome;
  1399.         }
  1400.  
  1401.     oldPos = (Rect **)Get1Resource(kWinPosType,iNum);    /* attempt to find saved window position        */
  1402.     stagRect = *iRect;
  1403.  
  1404.     if(oldPos && !opt)                                    /* (option key "forgets" old window */
  1405.         OffsetRect(&stagRect,
  1406.                 (**oldPos).left - stagRect.left,(**oldPos).top - stagRect.top);
  1407.  
  1408.         {
  1409.         Rect lilRect;
  1410.  
  1411.         lilRect.top = stagRect.top - 10;
  1412.         lilRect.left = stagRect.left + 4;
  1413.         lilRect.bottom = lilRect.top + 1;
  1414.         lilRect.right = lilRect.left + 1;
  1415.  
  1416.         rh = NewRgn();
  1417.         RectRgn(rh,&lilRect);
  1418.         SectRgn(rh,*(RgnHandle *)0x9EE,rh);
  1419.         if(EmptyRgn(rh) && gWindowsInView)
  1420.             OffsetRect(&stagRect,50 - iRect->left,80 - iRect->top);
  1421.  
  1422.         if(gStaggerWindows)
  1423.             {
  1424.             gStagX = (gStagX + gStagStepX)%kStagLimX;
  1425.             gStagY = (gStagY + gStagStepY)%kStagLimY;
  1426.             OffsetRect(&stagRect,gStagX,gStagY);
  1427.             }
  1428.         DisposeRgn(rh);
  1429.         }
  1430.  
  1431.     thisWindow->wUsed = 1;
  1432.  
  1433.     if(gHasColor)
  1434.         thisWindow->wWindow = NewCWindow(0,&stagRect,(StringPtr)iTitle,isVisible,
  1435.                 ((iFlags & wZoomable) != 0) ? zoomDocProc : iType,
  1436.                 (WindowPtr)-1,iGoAway!=0,0);
  1437.     else
  1438.         thisWindow->wWindow = NewWindow(0,&stagRect,(StringPtr)iTitle,isVisible,
  1439.                 ((iFlags & wZoomable) != 0) ? zoomDocProc : iType,
  1440.                 (WindowPtr)-1,iGoAway!=0,0);
  1441.  
  1442.     SetPort(thisWindow->wWindow);
  1443.  
  1444.     thisWindow->flags = iFlags;
  1445.     thisWindow->iNum = iNum < 0 ? -iNum : iNum;
  1446.     thisWindow->wUpdateProc = iUpdate;
  1447.     thisWindow->wClickProc = iClick;
  1448.     thisWindow->wKeyProc = iKey;
  1449.     thisWindow->wGoAwayProc = iGoAway;
  1450.     thisWindow->wZoomProc = nil;
  1451.     thisWindow->wActivateProc = iActivate;
  1452.     thisWindow->wDeactivateProc = iDeactivate;
  1453.     thisWindow->wIdleProc = iIdle;
  1454.     thisWindow->wResizeProc = nil;
  1455.     thisWindow->wGrowWindowProc = nil;
  1456.     thisWindow->wMoveWindowProc = nil;
  1457.     thisWindow->wEventProc = nil;
  1458.  
  1459. #ifdef BigEasyGXPrinting
  1460.     thisWindow->job = nil;
  1461. #endif
  1462.  
  1463. goHome:
  1464.     return thisWindow->wWindow;
  1465.     }
  1466.  
  1467.  
  1468. #ifdef BigEasyGXPrinting
  1469. void MakeSureWeHaveJob(TEasyWindow *thisWindow)
  1470.     {
  1471.     if(!thisWindow->job)
  1472.         if((thisWindow->flags & wPrintDraw) && gHasGX)
  1473.             {
  1474.             GoWatch();
  1475.             GXNewJob(&thisWindow->job);
  1476.             GoArrow();
  1477.             }
  1478.     }
  1479. #endif
  1480.  
  1481.  
  1482.  
  1483.  
  1484. void UninstallWindow(short iNum)
  1485.     {
  1486.     register TEasyWindow *thisWindow;
  1487.     register beDeactivateProcPtr fp;
  1488.  
  1489.     gCoolDragState = 0;                    /* just in case we were dragging the dissappeared window */
  1490.  
  1491.     if(!(thisWindow = GoodWNum(iNum)))
  1492.         return;
  1493.  
  1494.     SetPort(thisWindow->wWindow);
  1495.  
  1496.     fp = thisWindow->wDeactivateProc;
  1497.     if(fp)
  1498.         (*fp)(iNum);
  1499.     CloseWindow(thisWindow->wWindow);
  1500.     EnDisEdits(-1,-1,-1,-1,-1);
  1501.  
  1502. #ifdef BigEasyGXPrinting
  1503.     if((thisWindow->flags & wPrintDraw) && gHasGX)
  1504.         GXDisposeJob(thisWindow->job);
  1505. #endif
  1506.  
  1507.     thisWindow->wUsed = 0;
  1508.     }
  1509.  
  1510. void Show(short iNum)
  1511.     {
  1512.     register TEasyWindow *thisWindow;
  1513.  
  1514.     thisWindow = GoodWNum(iNum);
  1515.     if(thisWindow)
  1516.         {
  1517.         if(!((WindowPeek)(thisWindow->wWindow))->visible)    /* If so, just show it, and bring it to the front. */
  1518.             ShowWindow(thisWindow->wWindow);
  1519.         SelectWindow(thisWindow->wWindow);
  1520.         }
  1521.     }
  1522.  
  1523. void Hide(short iNum)
  1524. /*
  1525.   * Just do HideWindow to the
  1526.   * specified window number.
  1527.   */
  1528.     {
  1529.     register TEasyWindow *thisWindow;
  1530.  
  1531.     gCoolDragState = 0;                                    /* It might have been this window */
  1532.  
  1533.     thisWindow = GoodWNum(iNum);
  1534.     if(thisWindow)
  1535.         HideWindow(thisWindow->wWindow);
  1536.     }
  1537.  
  1538.     
  1539.  
  1540. void GetWindowRect(short n,Rect *r)
  1541. /*
  1542.   * return the window's current rectangle
  1543.   * in global coördinate space.
  1544.   */
  1545.     {
  1546.     TEasyWindow *thisWindow;
  1547.     WindowPtr g;
  1548.  
  1549.     if(!(thisWindow = GoodWNum(n)))
  1550.         return;
  1551.  
  1552.     if(thisWindow->wUsed)
  1553.         {
  1554.         g = thisWindow->wWindow;
  1555.         SetPort(g);
  1556.         *r = g->portRect;
  1557.         LocalToGlobal((Point *)r);
  1558.         LocalToGlobal((Point *)( (char*)r + 4));
  1559.         }
  1560.     }
  1561.         
  1562. WindowPtr GetWindowPtr(short n)
  1563. /*
  1564.   * return the windowptr for
  1565.   * the specified window number
  1566.   */
  1567.     {
  1568.     TEasyWindow *thisWindow;
  1569.     WindowPtr g;
  1570.  
  1571.     if(!(thisWindow = GoodWNum(n)))
  1572.         g = 0;
  1573.     else
  1574.         g = thisWindow->wWindow;
  1575.  
  1576.     return g;
  1577.     }
  1578.  
  1579. Boolean GetWindowVisible(short n)
  1580. /*
  1581.   * return true if the window exists,
  1582.   * and is visible, or false if its invisible
  1583.   * or doesn't exist.
  1584.   */
  1585.     {
  1586.     register WindowPtr g;
  1587.  
  1588.     g = GetWindowPtr(n);
  1589.     if(g)
  1590.         return ((WindowPeek)g)->visible;
  1591.     else
  1592.         return false;
  1593.     }
  1594.  
  1595. void SaveWindowPosition(short n)
  1596. /*
  1597.   * Save the position of window number n,
  1598.   * or all windows if n = -1;
  1599.   */
  1600.     {
  1601.     Rect **rH;
  1602.     register Rect *r;
  1603.     register short i;
  1604.     register short n1,n2;
  1605.     TEasyWindow *thisWindow;
  1606.  
  1607.     rH = (Rect **)NewHandleClear(sizeof(Rect));
  1608.     FailNil((long)rH);
  1609.     HLock((Handle)rH);
  1610.     r = *rH;
  1611.  
  1612.     if(n < 0)
  1613.         {
  1614.         n1 = 0;
  1615.         n2 = gEasyWindowListSize-1;
  1616.         }
  1617.     else
  1618.         n1 = n2 = n;
  1619.  
  1620.     for(i = n1; i<=n2; i++)
  1621.         {
  1622.         thisWindow = GoodWNum(i);
  1623.         if(thisWindow && thisWindow->wUsed)
  1624.             {
  1625.             GetWindowRect(i,r);
  1626.             if( !((WindowPeek)(thisWindow->wWindow))->visible )
  1627.                 SwapShort(r->left,r->right);
  1628.             Replace1Resource((Handle)rH,kWinPosType,i);
  1629.             }
  1630.         }
  1631.  
  1632.     DisposHandle( (Handle)rH );
  1633.     }
  1634.  
  1635. void ForgetWindowPosition(short n)
  1636. /*
  1637.   * Forget the saved window position n,
  1638.   * or all windows if n<0.
  1639.   */
  1640.     {
  1641.     register short i;
  1642.     register short n1,n2;
  1643.     register TEasyWindow *thisWindow;
  1644.  
  1645.     if(n < 0)
  1646.         {
  1647.         n1 = 0;
  1648.         n2 = gEasyWindowListSize-1;
  1649.         }
  1650.     else
  1651.         n1 = n2 = n;
  1652.  
  1653.     for(i = n1; i<=n2; i++)
  1654.         {
  1655.         thisWindow = GoodWNum(i);
  1656.         if(thisWindow && thisWindow->wUsed)
  1657.             Replace1Resource(0,kWinPosType,i);
  1658.         }
  1659.     }
  1660.  
  1661.  
  1662. void Replace1Resource(Handle h,long type,short id)
  1663. /*
  1664.   * This is AddResource with a
  1665.   * RmveResource if necessary.
  1666.   * Pass h==nil to delete the resource.
  1667.   */
  1668.     {
  1669.     Handle old;
  1670.  
  1671.     /*
  1672.      * A lame hack to prevent writing resources
  1673.      * to a lightspeed project file.
  1674.      */
  1675.     if( *(StringPtr)(0x910 + (*(StringPtr)0x910)) == 'π')
  1676.         {
  1677.         /* do nothing */
  1678.         }
  1679.     else
  1680.         {
  1681.  
  1682.         old = Get1Resource(type,id);
  1683.         if(old)
  1684.             RemoveResource(old);
  1685.         if(h)
  1686.             {
  1687.             AddResource(h,type,id,(StringPtr)"\p");
  1688.             WriteResource(h);
  1689.             DetachResource(h);
  1690.             }
  1691.  
  1692.         }
  1693.     }
  1694.  
  1695. void CheckMenubar(void)
  1696.     {
  1697.     if(gInvalidMenuBar)
  1698.         {
  1699.         DrawMenuBar();
  1700.         gInvalidMenuBar = false;
  1701.         }
  1702.     }
  1703.  
  1704. /*----------------
  1705.     Event Routines
  1706. ----------------*/
  1707.  
  1708. Boolean HandleUpdateEvent(EventRecord *er)
  1709. /*
  1710.  * Update the appropriate window, if we know who it is.
  1711.  */
  1712.     {
  1713.     Boolean result;
  1714.     short wNum;
  1715.     TEasyWindow *thisEasyWindow;
  1716.     WindowPtr w;
  1717.     GrafPtr oldPort;
  1718.  
  1719.     GetPort(&oldPort);
  1720.     result = false;
  1721.  
  1722.     if(er->what != updateEvt)
  1723.         {
  1724.         result = false;
  1725.         goto goHome;
  1726.         }
  1727.  
  1728.     w = (WindowPtr)er->message;
  1729.     wNum = ScanWindowList(w);                    /* other than null or click, scan list        */
  1730.     thisEasyWindow = GoodWNum(wNum);            /* and get record                    */
  1731.  
  1732.     if(thisEasyWindow)
  1733.         {
  1734.         Rect visBounds;
  1735.         beUpdateProcPtr fp;
  1736.  
  1737.         SetPort(w);
  1738.         BeginUpdate(w);
  1739.     
  1740.         result = true;
  1741.         visBounds = (**w->visRgn).rgnBBox;
  1742.         fp = thisEasyWindow->wUpdateProc;
  1743.         if(fp)
  1744.             {
  1745.             SetPort(thisEasyWindow->wWindow);                    /* Set port to window    */
  1746.             (*fp)(wNum);            /* Call drawing proc        */
  1747.             }
  1748.  
  1749.         SetOrigin(0,0);
  1750.  
  1751.         if (thisEasyWindow->flags & wGrowable)            /* Draw growbox, if...    */
  1752.             MyDrawGrowIcon(w);
  1753.  
  1754.         ClipRect(&gBigRect);
  1755.  
  1756.  
  1757.         DrawControls(w);
  1758.         EndUpdate(w);
  1759.         }
  1760.     else
  1761.         result = false;
  1762.  
  1763. goHome:
  1764.  
  1765.     SetPort(oldPort);
  1766.     return result;
  1767.     }
  1768.  
  1769.  
  1770. Boolean ActivateWindow(WindowPtr w, Boolean activate)
  1771.     {
  1772.     Boolean result;
  1773.     short wNum;
  1774.     TEasyWindow *thisEasyWindow;
  1775.     GrafPtr oldPort;
  1776.  
  1777.     GetPort(&oldPort);
  1778.  
  1779.     wNum = ScanWindowList(w);                    /* other than null or click, scan list        */
  1780.     thisEasyWindow = GoodWNum(wNum);            /* and get record                    */
  1781.  
  1782.     if(!thisEasyWindow)
  1783.         {
  1784.         result = false;
  1785.         goto goHome;
  1786.         }
  1787.  
  1788.     result = true;
  1789.  
  1790.     FrontDAEdits();
  1791.  
  1792.     if(thisEasyWindow)
  1793.         {
  1794.         SetPort(thisEasyWindow->wWindow);
  1795.         if(activate)
  1796.             {
  1797.             beActivateProcPtr fp;
  1798.             short copyItem,printItems;
  1799.  
  1800.             if(thisEasyWindow->flags & wCopyDraw)
  1801.                 copyItem = 1;
  1802.             else
  1803.                 copyItem = -1;
  1804.  
  1805.             EnDisEdits(-1,-1,copyItem,-1,-1);
  1806.  
  1807.             if(((thisEasyWindow->flags & wPrintDraw) && gHasGX)
  1808.                     || (gAppPageSetupProc && gAppPrintProc) )
  1809.                 printItems = 1;
  1810.             else
  1811.                 printItems = -1;
  1812.             SetMenuItem(mPageSetup,printItems,0,0,nil);
  1813.             SetMenuItem(mPrint,printItems,0,0,nil);
  1814.  
  1815.             fp = thisEasyWindow->wActivateProc;
  1816.             if(fp)
  1817.                 (*fp)(wNum);
  1818.             }
  1819.         else
  1820.             {
  1821.             beDeactivateProcPtr fp;
  1822.                         
  1823.             EnDisEdits(-1,-1,-1,-1,-1);
  1824.             SetMenuItem(mPageSetup,-1,0,0,nil);
  1825.             SetMenuItem(mPrint,-1,0,0,nil);
  1826.             fp = thisEasyWindow->wDeactivateProc;
  1827.             if(fp)
  1828.                 (*fp)(wNum);
  1829.             }
  1830.  
  1831.         InitCursor();
  1832.         if (thisEasyWindow->flags & wGrowable)            /* Draw growbox, if...    */
  1833.             MyDrawGrowIcon(w);
  1834.         }
  1835.  
  1836. goHome:
  1837.     SetPort(oldPort);
  1838.     return result;
  1839.     }
  1840.  
  1841. Boolean HandleActivateEvent(EventRecord *er)
  1842. /*
  1843.  * Handle it, if we can find out who it is.
  1844.  */
  1845.     {
  1846.     Boolean result;
  1847.  
  1848.     result = true;
  1849.  
  1850.     switch(er->what)
  1851.         {
  1852.         case activateEvt:
  1853.             ActivateWindow((WindowPtr)er->message,er->modifiers & 1);
  1854.             break;        
  1855.  
  1856.         case kOSEvent:
  1857.             switch ((unsigned long) er->message >> 24)    /*  high byte of message  */
  1858.                 {
  1859.                  case kSuspendResumeMessage:
  1860.                     ActivateWindow(FrontWindow(),er->modifiers & 1);
  1861.                     break;
  1862.                 default:
  1863.                     result = false;
  1864.                     break;
  1865.                 }
  1866.             break;
  1867.  
  1868.         default:
  1869.             result = false;
  1870.             break;
  1871.         }
  1872. goHome:
  1873.     return result;
  1874.     }
  1875.  
  1876.  
  1877.  
  1878.  
  1879.  
  1880. void EventLoop(void)
  1881.     {
  1882.     EventRecord er;
  1883.     short i;
  1884.     register short wNum;
  1885.     WindowPtr w;
  1886.     register TEasyWindow *thisEasyWindow;
  1887.     Boolean tookKey,tookEvent;
  1888.  
  1889.     CheckMenubar();
  1890.  
  1891.     WaitNextEvent(0xffff,&er,gSleep,nil);
  1892.         {
  1893.         gLastModifiers = er.modifiers;
  1894.         gLastEventTime = er.when;
  1895.  
  1896.         if(er.what > 5 && er.what < 12)                    /* update event or higher: in message    */
  1897.             w = (WindowPtr)er.message;
  1898.         else
  1899.             w = FrontWindow();                            /* else, use FrontW                    */
  1900.  
  1901.         if(er.what > 1)
  1902.             {
  1903.             wNum = ScanWindowList(w);                    /* other than null or click, scan list        */
  1904.             thisEasyWindow = GoodWNum(wNum);            /* and get record                    */
  1905.             }
  1906.         else
  1907.             thisEasyWindow = 0;
  1908.  
  1909.         SetPort(w);
  1910.  
  1911.         if(thisEasyWindow && thisEasyWindow->wEventProc)
  1912.             (*thisEasyWindow->wEventProc)(wNum,&er,&tookEvent);
  1913.         else
  1914.             tookEvent = 0;
  1915.  
  1916.         if(!tookEvent)
  1917.             switch (er.what)
  1918.                 {
  1919.                 case 0:    /* null event */
  1920.                     break;
  1921.     
  1922.                 case mouseDown:
  1923.                     FrontDAEdits();
  1924.                     DoMouseClick(&er);
  1925.                     break;
  1926.     
  1927.                 case keyDown:
  1928.                 case autoKey:
  1929.                     FrontDAEdits();
  1930.     
  1931.                     tookKey = false;
  1932.                     if( (!gMenuNeedsCmdKey) || (er.modifiers & 256) )
  1933.                         tookKey = DoKeyPress(er.message);
  1934.     
  1935.                     if(!tookKey && ((!gMenuNeedsCmdKey) || (er.modifiers & 256)) )
  1936.                         tookKey = CoolBigEasyCmdKeys(er.message & 0xFF);
  1937.     
  1938.                     if(!tookKey)
  1939.                         if(thisEasyWindow)
  1940.                             {
  1941.                             beKeyProcPtr fp;
  1942.                             
  1943.                             fp = thisEasyWindow->wKeyProc;
  1944.                             if(fp)
  1945.                                 {
  1946.                                 SetPort(thisEasyWindow->wWindow);                /* Set port to window    */
  1947.                                 (*fp)(wNum,            /* Call key proc        */
  1948.                                         (short)(er.message&0xff),            /* with the key */
  1949.                                         (short)((er.message>>8)&0xff),        /* the key code */
  1950.                                         er.modifiers);                        /* and the modifiers */
  1951.                                 }
  1952.                             }
  1953.                     break;
  1954.     
  1955.                 case updateEvt:
  1956.                     HandleUpdateEvent(&er);
  1957.                     break;
  1958.     
  1959.                 case activateEvt:
  1960.                     HandleActivateEvent(&er);
  1961.                     break;
  1962.     
  1963.                 case kOSEvent:
  1964.                     switch ((unsigned long) er.message >> 24)    /*  high byte of message  */
  1965.                         {
  1966.                          case kSuspendResumeMessage:
  1967.                             if(thisEasyWindow)                    /* just like activate event... */
  1968.                                 {
  1969.                                 ActivateWindow(FrontWindow(),
  1970.                                         er.message & kResumeMask);
  1971.                                 }
  1972.                         break;
  1973.                         }
  1974.                     break;
  1975.     
  1976.                 case kHighLevelEvent:
  1977.                     AEProcessAppleEvent(&er);
  1978.                     break;
  1979.                 case diskEvt:
  1980.                     if (er.message & 0xffff0000) {
  1981.                         Point where = {100,100};
  1982.                     //    DIBadMount(where, er.message);
  1983.                     }
  1984.                     break;    
  1985.                 default:
  1986.                     /*Debugger();/**/
  1987.                     ;
  1988.                 }
  1989.         }
  1990.  
  1991.     /*
  1992.       * See if we're doing a fake cool drag-window
  1993.       */
  1994.     if(gCoolDragState)
  1995.         {
  1996.         Point p,q;
  1997.  
  1998.         SetPort(gCoolDragEW->wWindow);
  1999.         GetMouse(&p);
  2000.         LocalToGlobal(&p);
  2001.         if( (p.v!=gCoolDragPoint.v) || (p.h!=gCoolDragPoint.h) )
  2002.             {
  2003.             q.h = gCoolDragEW->wWindow->portRect.left;
  2004.             q.v = gCoolDragEW->wWindow->portRect.top;
  2005.             LocalToGlobal(&q);
  2006.             MoveWindow(gCoolDragEW->wWindow,
  2007.                     q.h+p.h-gCoolDragPoint.h,
  2008.                     q.v+p.v-gCoolDragPoint.v,0);
  2009.             gCoolDragPoint = p;
  2010.  
  2011.                 {
  2012.                 beMoveWindowProcPtr fp;
  2013.  
  2014.                 fp = gCoolDragEW->wMoveWindowProc;
  2015.                 if(fp)
  2016.                     (fp)(gCoolDragWindowNumber);                    
  2017.                 }
  2018.  
  2019.             }
  2020.         if(!Button())
  2021.             gCoolDragState = 0;
  2022.         }
  2023.  
  2024.     SystemTask();
  2025.     w = FrontWindow();
  2026.     if ( w == gLastFrontIdle)                    /* Minor optimization, wins if the same        */
  2027.         wNum = gLastFrontWindowNumber;        /* window is frontmost for a while.            */
  2028.     else
  2029.         {
  2030.         wNum = ScanWindowList(w);
  2031.         gLastFrontIdle = w;
  2032.         gLastFrontWindowNumber = wNum;
  2033.         }
  2034.  
  2035.     if(er.what != mouseDown && er.what != activateEvt && !gQuitApp)    /* anything but a mousedown or [de]activate */
  2036.         {
  2037.         gIdleSeed ++;
  2038.         if(gIdleSeed & 1)    /* every other chance... */
  2039.             for(i = 1; i<gEasyWindowListSize; i++)
  2040.                 {
  2041.                 if(gEasyWindowList[i].wUsed && gEasyWindowList[i].wIdleProc)
  2042.                     {
  2043.                     SetPort(gEasyWindowList[i].wWindow);
  2044.                     (*gEasyWindowList[i].wIdleProc)
  2045.                             ((short)i,(Boolean)(w == gEasyWindowList[i].wWindow));
  2046.                     }
  2047.                 }
  2048.         }
  2049.  
  2050.     if (gMasterIdleProc && !gQuitApp)
  2051.         (*gMasterIdleProc)();
  2052.     }
  2053.  
  2054.  
  2055. Boolean CoolBigEasyCmdKeys(short key)
  2056.     {
  2057.     WindowRecord *w;
  2058.  
  2059.     switch(key)
  2060.         {
  2061.         /*
  2062.          * Rotate active window
  2063.          */
  2064.         case 9:        /* <tab> */
  2065.             w = *(WindowRecord **)0x9D6;        /* windowlist */
  2066.             if(w)
  2067.                 {
  2068.                 while (w->nextWindow)
  2069.                     w = w->nextWindow;
  2070.                 SelectWindow((WindowPtr)w);
  2071.                 }
  2072.             break;
  2073.  
  2074.         default:
  2075.             return false;
  2076.         }
  2077.     return true;
  2078.     }
  2079.  
  2080.  
  2081. void IdleWindow(short n)
  2082. /*
  2083.  * Idle window number n, or
  2084.  * -1 to idle all windows.
  2085.  */    
  2086.     {
  2087.     register short i;
  2088.     short lo,hi;
  2089.     WindowPtr w;
  2090.     register TEasyWindow *ew;
  2091.     GrafPtr oldPort;
  2092.  
  2093.     GetPort(&oldPort);
  2094.  
  2095.     if(n<0)
  2096.         {
  2097.         lo = 1;
  2098.         hi = gEasyWindowListSize;
  2099.         }
  2100.     else
  2101.         {
  2102.         lo = n;
  2103.         hi = n + 1;
  2104.         }
  2105.  
  2106.     w = FrontWindow();
  2107.     ew = &gEasyWindowList[lo];
  2108.  
  2109.     for(i = lo; i < hi; i++)
  2110.         {
  2111.         if(ew->wUsed && ew->wIdleProc)
  2112.             {
  2113.             SetPort(ew->wWindow);
  2114.             (*ew->wIdleProc)((short)i,ew->wWindow == w);
  2115.             }
  2116.         ew++;
  2117.         }
  2118.  
  2119.     SetPort(oldPort);
  2120.     SystemTask();
  2121.     }    
  2122.  
  2123. void MyDrawGrowIcon(WindowPtr w)
  2124.     {
  2125.     Rect r;
  2126.  
  2127.     SetPort(w);
  2128.     GetGrowRect(w,&r);
  2129.     ClipRect(&r);
  2130.     DrawGrowIcon(w);
  2131.     ClipRect(&gBigRect);
  2132.     }
  2133.  
  2134.  
  2135. void SetMasterOpenAppProc(beOpenAppProcPtr openAppProc)
  2136.     {
  2137.     gMasterOpenAppProc = openAppProc;
  2138.     if(gHasAppleEvents)
  2139.         AEInstallEventHandler(kCoreEventClass, kAEOpenApplication,
  2140.                 (AEEventHandlerUPP)BigEasyOpenAppThang, 0, false);
  2141.     }
  2142.  
  2143.  
  2144. void SetMasterOpenDocProc(beOpenDocProcPtr openDocProc)
  2145.     {
  2146.     gMasterOpenDocProc = openDocProc;
  2147.     if(gHasAppleEvents)
  2148.         AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments,
  2149.                 (AEEventHandlerUPP)BigEasyOpenDocThang, 0, false);
  2150.     }
  2151.  
  2152. void SetMasterQuitAppProc(beQuitAppProcPtr quitAppProc)
  2153.     {
  2154.     gMasterQuitAppProc = quitAppProc;
  2155.     }
  2156.  
  2157. pascal OSErr BigEasyOpenAppThang(AppleEvent *theEvent, AppleEvent *reply,long refCon)
  2158.     {
  2159.     #pragma unused (reply,refCon,theEvent)
  2160.     return noErr;
  2161.     }
  2162.  
  2163. pascal OSErr BigEasyOpenDocThang(AppleEvent *message, AppleEvent *reply,long refCon)
  2164.     {
  2165.     FSSpec fSpec;
  2166.     AEDescList docList;
  2167.     long index, itemsInList;
  2168.     Size actualSize;
  2169.     AEKeyword keywd;
  2170.     DescType typeCode;
  2171.     OSErr thisError;
  2172.     #pragma unused (reply,refCon)
  2173.  
  2174.     thisError = AEGetParamDesc(message, keyDirectObject, typeAEList, &docList);
  2175.     if(thisError)
  2176.         goto goHome;
  2177.  
  2178.     thisError = MissedAEParameters(message);
  2179.     if(thisError)
  2180.         goto goHome;
  2181.  
  2182.     thisError = AECountItems(&docList, &itemsInList);
  2183.     if(thisError)
  2184.         goto goHome;
  2185.  
  2186.     for (index = 1; index <= itemsInList; index++)
  2187.         {
  2188.         thisError = AEGetNthPtr(&docList, index, typeFSS, &keywd, &typeCode,
  2189.                     (Ptr)&fSpec, sizeof(FSSpec), &actualSize);
  2190.         if(thisError)
  2191.             goto goHome;
  2192.  
  2193.         if(gMasterOpenDocProc)
  2194.             (*gMasterOpenDocProc)(&fSpec);
  2195.         }
  2196.  
  2197.     thisError = AEDisposeDesc(&docList);
  2198.  
  2199. goHome:
  2200.     return thisError;
  2201.     }
  2202.  
  2203. pascal OSErr BigEasyQuitAppThang(AppleEvent *theEvent, AppleEvent *reply,long refCon)
  2204.     {
  2205.     OSErr thisError;
  2206.     #pragma unused (reply,refCon)
  2207.  
  2208.     thisError = MissedAEParameters(theEvent);
  2209.     if (!thisError)
  2210.         {
  2211.         ++ gQuitApp;
  2212.     
  2213.         if(gMasterQuitAppProc)
  2214.             (*gMasterQuitAppProc)();
  2215.         }
  2216.  
  2217.     return thisError;
  2218.     }
  2219.  
  2220. OSErr MissedAEParameters (AppleEvent *message)
  2221.     {
  2222.     DescType typeCode;
  2223.     Size actualSize;
  2224.     OSErr err;
  2225.  
  2226.     err = AEGetAttributePtr(message, keyMissedKeywordAttr, typeWildCard,
  2227.             &typeCode, nil, 0L, &actualSize);
  2228.     if (err == errAEDescNotFound)
  2229.         return(noErr);
  2230.     return(err = noErr ? errAEEventNotHandled : err);
  2231.     }
  2232.  
  2233.  
  2234.  
  2235.  
  2236. void InitBigEasy(void)
  2237.     {
  2238.     long result;
  2239.  
  2240.     gMasterOpenAppProc = nil;
  2241.     gMasterOpenDocProc = nil;
  2242.     gMasterIdleProc = nil;
  2243.     gAboutProc = nil;
  2244.     gQuitApp = false;
  2245.     gMenuNeedsCmdKey = true;
  2246.     gStaggerWindows = true;
  2247.     gWindowsInView = true;
  2248.     gSleep = 0;
  2249.     gInvalidMenuBar = false;
  2250.  
  2251.     gStagStepX = 7;
  2252.     gStagStepY = 7;
  2253.  
  2254.     SetRect(&gBigRect,-16000,-16000,16000,16000);
  2255.  
  2256.     gEasyWindowListH = (TEasyWindow**)NewHandleClear(sizeof(TEasyWindow));
  2257.     HLock((Handle)gEasyWindowListH);
  2258.     gEasyWindowList = *gEasyWindowListH;
  2259.     gEasyWindowList[0].wUsed = 0;
  2260.     gEasyWindowListSize = 1;
  2261.  
  2262.     gLastFrontIdle = (WindowPtr) 0;
  2263.     gLastFrontWindowNumber = -1;
  2264.  
  2265.     gCoolDragState = 0;
  2266.  
  2267.  
  2268. /*
  2269.  * 7.0 Feature stuff
  2270.  */
  2271.     gSystemVersion = (Gestalt('sysv', &result)) ? 0 : result;
  2272.     gHasAppleEvents = (Gestalt(gestaltAppleEventsAttr, &result) ? false : result != 0);
  2273.     gHasColor = (Gestalt('qdrw',&result)) ?
  2274.             false : (result & (1<<gestaltHasDeepGWorlds)) != 0;
  2275.  
  2276.     /*
  2277.      * The quit-app message, if available.
  2278.      */
  2279.     gMasterQuitAppProc = nil;
  2280.     if(gHasAppleEvents)
  2281.         AEInstallEventHandler(kCoreEventClass, kAEQuitApplication,
  2282.                 (AEEventHandlerUPP)BigEasyQuitAppThang, 0, false);
  2283.  
  2284. /*
  2285.  * GX Feature stuff
  2286.  */
  2287.  
  2288. #ifdef BigEasyGXPrinting
  2289.     gHasGX = WantsGX
  2290.             && ( (Gestalt(gestaltGXVersion,&result)) ? false : true );
  2291.  
  2292.     if(gHasGX)
  2293.         {
  2294.         GXEnterGraphics();
  2295.         GXInitPrinting();
  2296.         }
  2297. #else
  2298.     gHasGX = false;
  2299. #endif
  2300.  
  2301.  
  2302.     }
  2303.  
  2304. static void ExitBigEasy(void)
  2305.     {
  2306. #ifdef BigEasyGXPrinting
  2307.     if(gHasGX)
  2308.         {
  2309.         GXExitGraphics();
  2310.         GXExitPrinting();
  2311.         }
  2312. #endif
  2313.     }
  2314.  
  2315. void main(void)
  2316.     {
  2317. #if 0
  2318. #ifdef THINK_C_PROFILE
  2319.     freopen("profile output","w+",stdout);
  2320.  
  2321.     InitProfile(1000,50);
  2322. #endif THINK_C_PROFILE    
  2323. #endif
  2324.  
  2325.     MaxApplZone();
  2326.     MoreMasters();
  2327.     MoreMasters();
  2328.  
  2329.     InitToolbox();
  2330.     StartMenus();
  2331.  
  2332.     InitBigEasy();
  2333.     Bootstrap();
  2334.     
  2335.     #if THINK_C >= 5
  2336.         #if defined(STACK_KILLER) || defined(TIMING_PROFILE)
  2337.             prepStackKiller();        /** slime from HELL **/
  2338.             #ifdef TIMING_PROFILE
  2339.                 InitTimingProfile(150);    /* call depth */
  2340.             #endif TIMING_PROFILE
  2341.         #endif
  2342.     #endif
  2343.  
  2344.     while (!gQuitApp)
  2345.         EventLoop();
  2346.  
  2347.     FlushEvents(0xffff,0);
  2348.  
  2349.     #ifdef TIMING_PROFILE
  2350.         DumpProfile(0, 0, "\ptiming stats");
  2351.     #endif
  2352.     
  2353.     Hatstrap();
  2354.     ExitBigEasy();
  2355.     ExitToShell();
  2356.     }
  2357.  
  2358.